import * as React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import withSizes from 'react-sizes';
import { formatMessage, FormattedMessage } from 'umi/locale';
import {
  Button,
  Checkbox,
  Col,
  DatePicker,
  Form,
  Icon,
  Input,
  InputNumber,
  Popconfirm,
  Row,
  Select,
} from 'antd';
import uiUtils from '@/utils/uiUtils';

const FormItem = Form.Item;
const Option = Select.Option;
const RangePicker = DatePicker.RangePicker;
const MonthPicker = DatePicker.MonthPicker;

/**
 {
  xs: '480px',
  sm: '576px',
  md: '768px',
  lg: '992px',
  xl: '1200px',
  xxl: '1600px',
 */
let COLUME_MAX = 3; //主流pc屏幕每一行多少列
const colSpanLayout = { xxl: 6, xl: 6, lg: 8, md: 10, sm: 10, xs: 24 }; //每一col跨?列
const rowGutterPxLayout = { xxl: 48, xl: 40, lg: 32, md: 24, sm: 16, xs: 8 }; //col之间的间隔?px

//INPUT、SELECT、DATE_RANGE、DATE、SELECT_REMOTE、INPUT_RANGE
//输入框、下拉框（含搜索）、日期范围、日期、远程下拉框、输入框范围<整数>
class FilterForm extends React.Component {
  static propTypes = {
    formList: PropTypes.array,
    filterSubmit: PropTypes.func,
    loading: PropTypes.bool,
    //下面属性是组件包裹层就已经提供了
    isXl: PropTypes.bool,
    isMdOrSm: PropTypes.bool,
    isLg: PropTypes.bool,
  };

  static defaultProps = {
    formList: [], //表单布局数组
    filterSubmit: () => {
      //点击提交的回调事件
    },
    loading: false, //是否在loading状态
    //bootstrap规定的lg,md,sm,xs，这里进行动态获取屏幕大小
    isXl: false,
    isMdOrSm: false,
    isLg: false,
  };

  constructor(props) {
    super(props);
    this.state = {
      expand: false,
    };
    if (this.props.isXl || this.props.isMdOrSm) {
      COLUME_MAX = 4;
    } else if (this.props.isLg) {
      COLUME_MAX = 3;
    }
  }

  //这里点击搜索的回调事件
  handleFilterSubmit = () => {
    //2.0 DatePicker 在 this.props.form.getFieldsValue()下返回moment对象时区问题
    //DatePicker onChange 需要得到 format 后的值
    //希望form表单提交的时候能够获取到标准化的值（非normalize） https://github.com/ant-design/ant-design/issues/11935
    const fieldsValue = this.props.form.getFieldsValue();

    //这里对数据进行处理
    const record = {};
    Object.keys(fieldsValue).forEach(key => {
      const field = this.findFormItemByField(key);
      if (fieldsValue[key]) {
        if (field.type === 'DATE') {
          //时间类型
          record[key] = fieldsValue[key].format(field.format ? field.format : 'YYYY-MM-DD');
        } else if (field.type === 'DATE_RANGE') {
          //时间间隔
          if (fieldsValue[key][0] && fieldsValue[key][1]) {
            record[`${key}_BETWEEN`] = `${fieldsValue[key][0].format('YYYY-MM-DD')} - ${fieldsValue[
              key
            ][1].format('YYYY-MM-DD')}`;
          } else {
            record[`${key}_BETWEEN`] = null;
          }
        } else if (field.type === 'INPUT_RANGE') {
          record[`${key}_RANGE`] = `${fieldsValue[key][0]}_${fieldsValue[key][1]}`;
        } else if (field.type === 'UPLOAD' || field.type === 'IMAGE') {
          //上传或者图片
          record[key] = fieldsValue[key].map(item => item.response.url);
        } else {
          //其他
          record[key] = fieldsValue[key];
        }
      } else {
        record[key] = null;
      }
    });
    this.props.filterSubmit(record);
  };

  findFormItemByField = field =>
    this.props.formList.find((value, index, arr) => field === value.field);

  // 重置form表单
  reset = () => {
    this.props.form.resetFields();
  };

  toggle = () => {
    const { expand } = this.state;
    this.setState({ expand: !expand });
  };

  warpFormItem = (formItem, isDisplay) => (
    <Col {...colSpanLayout} style={{ display: isDisplay ? 'block' : 'none' }}>
      {formItem}
    </Col>
  );

  initFormBtn = () => {
    let formBtn;
    if (this.state.expand) {
      formBtn = (
        <Row style={{ float: 'right', marginBottom: 0, marginRight: 20 }}>
          <Col span={24}>
            <Button
              type="primary"
              icon="search"
              loading={this.props.loading}
              onClick={this.handleFilterSubmit}
            >
              <FormattedMessage id="ours.curd.list.base-form.search" defaultMessage="查询" />
            </Button>
            <Popconfirm
              title={formatMessage({ id: `ours.curd.list.are.you.sure` })}
              onConfirm={this.reset}
              icon={<Icon type="question-circle-o" style={{ color: 'red' }} />}
            >
              <Button style={{ marginLeft: 8 }} icon="rollback">
                <FormattedMessage id="ours.curd.list.base-form.reset" defaultMessage="重置" />
              </Button>
            </Popconfirm>
            <a
              style={{
                marginLeft: 8,
                fontSize: 12,
                display: this.props.formList.length < COLUME_MAX ? 'none' : 'inline',
              }}
              onClick={this.toggle}
            >
              <FormattedMessage id="ours.curd.list.base-form.expand" defaultMessage="收起" />{' '}
              <Icon type="up" />
            </a>
          </Col>
        </Row>
      );
    } else {
      formBtn = (
        <Col {...colSpanLayout}>
          <Button
            type="primary"
            icon="search"
            loading={this.props.loading}
            onClick={this.handleFilterSubmit}
          >
            <FormattedMessage id="ours.curd.list.base-form.search" defaultMessage="查询" />
          </Button>
          <Popconfirm
            title={<FormattedMessage id="ours.curd.are-you-sure" defaultMessage="确定吗？" />}
            onConfirm={this.reset}
            icon={<Icon type="question-circle-o" style={{ color: 'red' }} />}
          >
            <Button style={{ marginLeft: 8 }} icon="rollback">
              <FormattedMessage id="ours.curd.list.base-form.reset" defaultMessage="重置" />
            </Button>
          </Popconfirm>
          <a
            style={{
              marginLeft: 8,
              fontSize: 12,
              display: this.props.formList.length < COLUME_MAX ? 'none' : 'inline',
            }}
            onClick={this.toggle}
          >
            <FormattedMessage id="ours.curd.list.base-form.expand" defaultMessage="展开" />{' '}
            <Icon type="down" />
          </a>
        </Col>
      );
    }
    return formBtn;
  };

  initFormList = () => {
    const { getFieldDecorator } = this.props.form;
    const formList = this.props.formList;
    const formItemList = [];
    const count = this.state.expand ? 1024 : COLUME_MAX - 1;

    if (formList && formList.length > 0) {
      formList.forEach((item, i) => {
        const label = item.label;
        const field = item.field;
        const placeholder = item.placeholder;

        if (item.type === 'INPUT') {
          const initialValue = item.initialValue || '';

          const INPUT = (
            <FormItem label="" key={field}>
              {getFieldDecorator([field], {
                initialValue,
              })(
                <Input
                  type="text"
                  style={{ width: '100%' }}
                  placeholder={placeholder}
                  autocomplete="off"
                  onPressEnter={this.handleFilterSubmit}
                />
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(INPUT, i < count));
        } else if (item.type === 'SELECT') {
          const {
            type,
            initialValue = '',
            showSearch = false,
            list = [],
            onChange = () => {},
            ...rest
          } = item;
          //https://ant.design/components/select-cn/
          //先支持：默认值、筛选、分组
          //是否显示搜索
          const showSearchs = showSearch
            ? {
                showSearch: true,
                filterOption: (input, option) =>
                  option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0,
              }
            : {
                showSearch: false,
              };

          const SELECT = (
            <FormItem label="" key={field}>
              {getFieldDecorator([field], {
                initialValue,
              })(
                <Select
                  style={{ width: '100%' }}
                  allowClear
                  {...showSearchs}
                  {...rest}
                  onChange={value => {
                    onChange(value);
                  }}
                >
                  {uiUtils.getOptionList(list)}
                </Select>
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(SELECT, i < count));
        } else if (item.type === 'CHECKBOX') {
          const initialValue = item.initialValue || '';

          const CHECKBOX = (
            <FormItem label="" key={field}>
              {getFieldDecorator([field], {
                valuePropName: 'checked',
                initialValue, // true | false
              })(<Checkbox>{label}</Checkbox>)}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(CHECKBOX, i < count));
        } else if (item.type === 'DATE') {
          const format = item.format;
          const showTime = item.showTime;

          const showTimeObj =
            showTime !== null &&
            showTime !== '' &&
            showTime !== undefined &&
            ((typeof showTime === 'string' && showTime === 'true') ||
              (typeof showTime === 'boolean' && showTime === true))
              ? 'showTime'
              : '';
          const Date = (
            <FormItem label="" key={field}>
              {getFieldDecorator([field])(
                <DatePicker
                  style={{ width: '100%' }}
                  showTime={showTimeObj}
                  defaultValue={moment()}
                  placeholder={placeholder}
                  onChange={(date, dateString) => {
                    //段大志修改
                    this.props.form.setFieldsValue({
                      [field]: date,
                    });
                    this.handleFilterSubmit();
                  }}
                  format={
                    format !== null && format !== '' && format !== undefined
                      ? format
                      : 'YYYY-MM-DD HH:mm:ss:SSS'
                  }
                />
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(Date, i < count));
        } else if (item.type === 'DATE_RANGE') {
          //时间区间范围
          //RangePicker placeholder 是数组形式：['开始时间','结束时间']

          const placeholders =
            placeholder === null || placeholder === '' || placeholder === undefined
              ? ['请选项开始时间', '']
              : placeholder;
          const rangePicker = (
            <FormItem label="" key={field}>
              {getFieldDecorator([`${field}`], {
                //转换默认的 value 给控件，
                normalize: (value, prevValue, allValues) => value,
                //收集子节点的值的时机
                trigger: 'onChange',
              })(
                <RangePicker
                  placeholder={placeholders}
                  defaultValue={[moment(), moment()]}
                  onChange={(dates, dateStrings) => {
                    this.props.form.setFieldsValue({
                      [field]: dates,
                    });
                    this.handleFilterSubmit();
                  }}
                  format="YYYY-MM-DD"
                />
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(rangePicker, i < count));
        } else if (item.type === 'INPUT_RANGE') {
          const initialValue = item.initialValue || '';
          const placeholders =
            placeholder === null || placeholder === '' || placeholder === undefined
              ? ['请输入起始区间数', '请输入起始区间数']
              : placeholder;
          const rangePicker = (
            <FormItem label="" key={field}>
              {getFieldDecorator([`${field}[0]`], {
                initialValue,
              })(
                <InputNumber
                  type="text"
                  style={{ width: '45%' }}
                  placeholder={placeholders[0]}
                  id="value1"
                  min={0}
                  max={99999999}
                  autocomplete="off"
                  onPressEnter={this.handleFilterSubmit}
                />
              )}
              &nbsp;至&nbsp;
              {getFieldDecorator([`${field}[1]`], {
                initialValue,
              })(
                <InputNumber
                  type="text"
                  style={{ width: '45%' }}
                  placeholder={placeholders[1]}
                  min={0}
                  max={99999999}
                  id="value2"
                  autocomplete="off"
                  onPressEnter={this.handleFilterSubmit}
                />
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(rangePicker, i < count));
        } else if (item.type === 'SELECT_REMOTE') {
          //远程搜索select
          const list = item.list;
          const onSearch = item.handleRemoteSearch;

          const selectRemote = (
            <FormItem label="" key={field}>
              {getFieldDecorator([field])(
                <Select
                  style={{ width: '100%' }}
                  placeholder={placeholder}
                  allowClear
                  showSearch
                  autoClearSearchValue
                  defaultActiveFirstOption={false}
                  showArrow={false}
                  filterOption={false}
                  notFoundContent={null}
                  onSearch={onSearch}
                  onChange={this.handleFilterSubmit}
                >
                  {uiUtils.getOptionList(list)}
                </Select>
              )}
            </FormItem>
          );
          formItemList.push(this.warpFormItem(selectRemote, i < count));
        }
      });
    }
    return formItemList;
  };

  render() {
    return (
      <Form layout="horizontal">
        {/* gutter 设置栅格之间的间隔 */}
        <Row gutter={{ ...rowGutterPxLayout }}>
          {this.initFormList()}
          {this.initFormBtn()}
        </Row>
      </Form>
    );
  }
}

/**
 * https://github.com/renatorib/react-sizes
 * 获取屏幕的宽度
 * @param width
 * @returns {{isXl: boolean}}
 *
 * withSizes函数动态获取父组件的屏幕尺寸
 */
const mapSizesToProps = ({ width }) => ({
  isXl: width > 1200,
  isMdOrSm: width > 576 && width <= 768,
  isLg: width > 768 && width <= 992,
});

export default withSizes(mapSizesToProps)(Form.create({})(FilterForm));
